Skip to content

feat: add read-only Gateway TUI - #1956

Open
aidandaly24 wants to merge 10 commits into
refactorfrom
feat/gateway-read-tui
Open

feat: add read-only Gateway TUI#1956
aidandaly24 wants to merge 10 commits into
refactorfrom
feat/gateway-read-tui

Conversation

@aidandaly24

@aidandaly24 aidandaly24 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • launch bare Gateway branches and read leaves into the TUI through the shared Handler tree while preserving flag-driven headless JSON behavior
  • align TUI routes with the CLI command hierarchy for Gateway, Target, Connector, and Rule get/list
  • use staged Gateway selection for nested resources, with direct bare get routes redirecting through the corresponding list flow
  • present Connector as a separate resource experience while continuing to use Gateway Target APIs internally
  • keep parent selection and scoped resource listing in dedicated Gateway, Target, Connector, and Rule picker components
  • centralize Connector get/list filtering and validation in GatewayClient, with CLI and TUI consumers delegating through CoreGatewayClient
  • fill Connector pages to maxResults, cap discovery at 101 Target pages, and use lookahead so nextToken is returned only when another Connector exists
  • use router-level supportedTuiCommands so read commands enter the TUI while bare CLI-only create commands run normal validation
  • reuse the established router menu, paginated table, resource detail, JSON, loading, retry, empty, keyboard, and responsive layout components

Testing

  • bun test src/handlers/gateway/gateway.test.tsx src/handlers/gateway/gateway.screen.test.tsx src/handlers/gateway/gateway.fixture.test.tsx src/core/gateway.test.ts src/components/ui/data-table/columnWidths.test.ts (88 pass)
  • bun test --coverage --coverage-reporter=text (1081 pass; 93.73% functions, 97.88% lines)
  • bun run typecheck
  • bun run lint:check
  • bun run format:check
  • bun run build
  • npm pack --ignore-scripts
  • help smoke for Gateway root plus all eight get/list leaves (12/12)
  • TUI harness at 100x30, confirming Gateway and Connector menus expose read-only commands only
  • deploy-account pagination probe: reused a ListGatewayTargets token created with maxResults=2 in a request with maxResults=1, returning the next distinct Target
  • RECORD=1 AWS_PROFILE=e2e-test bun test src/handlers/gateway/gateway.fixture.test.tsx -t 'lists Gateway Connectors'

The full source run retains seven local src/io/exec.test.ts failures plus three associated errors on files byte-identical to origin/refactor.

@github-actions github-actions Bot added the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 7, 2026
@codecov-commenter

codecov-commenter commented Aug 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.33665% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.88%. Comparing base (1e7de20) to head (9d530a5).

Files with missing lines Patch % Lines
src/handlers/gateway/get/screen.tsx 95.94% 3 Missing ⚠️
src/components/GatewayConnectorPicker.tsx 98.11% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           refactor    #1956      +/-   ##
============================================
+ Coverage     96.79%   96.88%   +0.08%     
============================================
  Files           306      322      +16     
  Lines         17051    17634     +583     
============================================
+ Hits          16505    17085     +580     
- Misses          546      549       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 7, 2026
@aidandaly24
aidandaly24 marked this pull request as draft August 10, 2026 14:47
@aidandaly24 aidandaly24 reopened this Aug 10, 2026
@github-actions github-actions Bot added agentcore-harness-reviewing AgentCore Harness review in progress and removed agentcore-harness-reviewing AgentCore Harness review in progress labels Aug 10, 2026
@aidandaly24
aidandaly24 force-pushed the feat/gateway-read-tui branch 3 times, most recently from e5fda21 to c710a7a Compare August 10, 2026 22:10
@aidandaly24
aidandaly24 marked this pull request as ready for review August 11, 2026 01:31
@aidandaly24

Copy link
Copy Markdown
Contributor Author

Gateway read-only TUI demo

Gateway read-only TUI demo

Download the MP4

Recorded with the real TUI components and synthetic Gateway/Connector data. No AWS account or credential metadata is included.

jariy17
jariy17 previously approved these changes Aug 11, 2026

@jariy17 jariy17 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a follow up pr? It's pretty god

Comment thread src/core/gateway.tsx Outdated
const items: TargetSummary[] = [];
let token = nextToken;

while (true) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unbounded scan, we should throw a truncationError like this. Should be more than gateway_limit (100)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

▎ Flagging a second issue in this block, separate from the unbounded scan.

▎ Early stop. const full = maxResults === undefined ? items.length > 0 : .... On the no-maxResults path, items.length > 0 returns after the first Target page that yields any connector. So a Gateway with 30 connectors can return just the 2 that
▎ landed in page 1. Every other list returns a full service page. This one doesn't.

▎ Wrong token. return { ...response, items } returns response.nextToken, which is a ListGatewayTargets token. It means more Targets remain, not more Connectors. The TUI surfaces a "more →" affordance whenever a token is present, so a user can
▎ page forward into an empty Connector screen while connectors still exist deeper in the Target stream.

▎ Fix: treat the undefined case like the numeric one. Fill to a default page size instead of stopping at the first hit, so the page and its token stay connector-aligned. At minimum, add a comment that the token paginates Targets, not
▎ Connectors.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 24f49f8. Connector discovery is now capped at 101 Target pages (one above the documented default 100-target Gateway quota) and throws the merged ResultTruncationError instead of scanning indefinitely or returning partial results. I added an ever-advancing-token regression test that verifies the cap.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 24f49f8. An omitted maxResults now fills a 100-row logical Connector page instead of stopping at the first hit. After a page fills, Core looks ahead and returns the service token used to fetch the first later Target page known to contain a Connector; if none exists, nextToken is omitted. This keeps AWS tokens, avoids buffered/custom token state, and prevents a false "more" page. Added focused tests for default filling, aligned lookahead, and exhausted lookahead.

import { PaginatedTablePicker } from "./PaginatedTablePicker";
import type { DataTableColumn } from "./ui/data-table";

interface GatewayRuleRow extends Record<string, unknown> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wow, all these common components make this so easy to read!

Comment thread src/core/gateway.tsx
let token = nextToken;
let filling = true;

for (let page = 0; page < MAX_CONNECTOR_TARGET_PAGES; page++) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the api not support server side filtering? if so that feels like a major gap, especially if this is a common customer use-case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't support it at the moment. We could probably request Gateway do it. But I wonder if since they haven't, maybe it really isn't that useful to the customer...

This could be removed for just gateway target list/get. I think that would make sense. But we wanted to separate connector for CUD because it is helpful for containing flags to specific use cases.

Comment thread src/handlers/gateway/gateway.test.tsx Outdated
["Rule list", ["gateway", "rule", "list"]],
] as const)("opens the TUI for a bare %s command", async (_label, args) => {
await expect(run([...args])).rejects.toThrow(
"interactive mode requires a TTY on stdin and stdout",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a way to make this test more explicit? Right now we're relying on the behavior that tty is required for this test to work.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Fixed in 9d530a5. The Gateway test now compiles the real command tree and asserts isTuiCommandSupported directly for every read path, plus false for each CLI-only create path. The create cases still assert normal handler validation, while the generic TTY dispatch behavior remains owned by the middleware unit test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants